package com.ht.modules.system.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import jakarta.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.shiro.SecurityUtils;
import com.ht.entity.LoginUser;
import com.ht.modules.system.entity.DataRule;
import com.ht.modules.system.service.IDataRuleService;
import com.ht.modules.system.service.ISysDepartService;
import com.ht.modules.system.service.ISysUserRoleService;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.springframework.stereotype.Component;

/**
 * @Author: gaozhihua
 * @Date: 2021年8月16日16:59:13
 */
@Component
public class DataRuleUtil {

	private static final String conditionCategoryCurrentUser = "currentUser";
	private static final String conditionCategoryCurrentDepart = "currentDepart";
	private static final String conditionCategoryCurrentRole = "currentRole";
	private static final String conditionsIn = "in";
	private static final String conditionsNotIn = "notin";

	private static final String dataJudgeCategoryUser = "user";
	private static final String dataJudgeCategoryDepart = "depart";
	private static final String dataJudgeCategorySql = "sql";
	private static final String dataJudgeCategoryCurrentUserId = "currentUserId";
	/**
	 * 拼装sql语句
	 * @param request
	 * @return
	 */
	 public static String getSql(HttpServletRequest request) {
		 IDataRuleService dataRuleService = ApplicationContextUtil.getContext().getBean(IDataRuleService.class);
		 ISysDepartService sysDepartService = ApplicationContextUtil.getContext().getBean(ISysDepartService.class);
		 ISysUserRoleService sysUserRoleService = ApplicationContextUtil.getContext().getBean(ISysUserRoleService.class);
		 String requestPath = request.getServletPath();
		 List<DataRule> listUrlConcatStr = dataRuleService.listUrlConcatStr(requestPath);
		 LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		String queryUserDeparts = sysDepartService.getDepartIdByCode(sysUser.getOrgCode());
		 String result = "";
		 for (DataRule dataRule : listUrlConcatStr) {
			if(!"".equals(result)) {
				return result;
			}
			switch (dataRule.getConditionCategory()) {
			case conditionCategoryCurrentUser:
				switch (dataRule.getConditions()) {
				case conditionsIn:
					if(ArrayUtils.contains(dataRule.getConditionResults().split(","), sysUser.getId())) {
					result =	getResultSql(dataRule,sysUser.getId());
					}
					break;
				case conditionsNotIn:
					if(!ArrayUtils.contains(dataRule.getConditionResults().split(","), sysUser.getId())) {
						result =	getResultSql(dataRule,sysUser.getId());
						}
					break;

				default:
					result = "and 1!=1";
					break;
				}
				break;
			case conditionCategoryCurrentDepart:

				switch (dataRule.getConditions()) {
				case conditionsIn:
					if(ArrayUtils.contains(dataRule.getConditionResults().split(","), queryUserDeparts)) {
					result =	getResultSql(dataRule,sysUser.getId());
					}
					break;
				case conditionsNotIn:
					if(!ArrayUtils.contains(dataRule.getConditionResults().split(","), queryUserDeparts)) {
						result =	getResultSql(dataRule,sysUser.getId());
						}
					break;

				default:
					result = "and 1!=1";
					break;
				}
				break;
			case conditionCategoryCurrentRole:
				String roleIdByUserId = sysUserRoleService.getRoleIdByUserId(sysUser.getId());
				switch (dataRule.getConditions()) {
				case conditionsIn:
					if(contain(dataRule.getConditionResults(), roleIdByUserId)) {
					result =	getResultSql(dataRule,sysUser.getId());
					}
					break;
				case conditionsNotIn:
					if(!contain(dataRule.getConditionResults(), roleIdByUserId)) {
						result =	getResultSql(dataRule,sysUser.getId());
						}
					break;

				default:
					result = "and 1!=1";
					break;
				}
				break;

			default:
				result = "and 1!=1";
				break;
			}
		}
	        return result;
	    }
	/**
	 * 处理结果集，方法一样 单独拿出来了
	 * @param dataRule
	 * @param userId
	 * @return
	 */
	 private static String getResultSql(DataRule dataRule,String userId) {
		String sql = "";
		 switch (dataRule.getDataJudgeCategory()) {
		case dataJudgeCategoryUser:
			sql = assembleSql(dataRule);
			break;
		case dataJudgeCategoryDepart:
			sql = assembleSql(dataRule);
					break;
		case dataJudgeCategorySql:
			sql = dataRule.getDataJudgeResults();
			break;
		case dataJudgeCategoryCurrentUserId:
			//获取当前用户id传过去
			sql = currentUserIdSql(dataRule, userId);
			break;

		}
		 return sql;
	 }
	 /**
	  * 拼装非获取当前用户数据sql
	  * @param dataRule
	  * @return
	  */
	 private static String assembleSql(DataRule dataRule) {
		 StringBuffer sb = new StringBuffer();
		 sb.append("and");
		 sb.append(" ");
		 sb.append(dataRule.getTableName());
			sb.append(".");
			sb.append(dataRule.getFieldName());
			sb.append(" ");
			sb.append("in");
			sb.append(" (");
			for (String iterable_element : dataRule.getDataJudgeResults().split(",")) {
				sb.append("'");
				sb.append(iterable_element);
				sb.append("'");
				sb.append(",");
			}
			String string = sb.toString();
			if(sb.toString().endsWith(",")) {
				string = string.substring(0, string.length()-1);
			}
			string = string+")";
		 return string;
	 }
	 /**
	  * 当是当前用户时 拼装sql
	  * @param dataRule
	  * @param userId
	  * @return
	  */
	private static String currentUserIdSql(DataRule dataRule, String userId) {
		StringBuffer sb = new StringBuffer();
		sb.append("and");
		sb.append(" ");
		sb.append(dataRule.getTableName());
		sb.append(".");
		sb.append(dataRule.getFieldName());
		sb.append(" ");
		sb.append("=");
		sb.append("'");
		sb.append(userId);
		sb.append("'");
		return sb.toString();
	}
	 /**
	  * 判断list1是否包含list2的内容
	  * @param list1
	  * @param list2
	  * @return
	  */
	 private static boolean contain(String list1,String list2) {
			for (String string : list1.split(",")) {
				for (String string2 : list2.split(",")) {
					if(string.equals(string2)) {
						return true;
					}
				}
			}
			return false;
	 }
	 //获取可看userid的集合
	 //当数据没有数据库时(完全是几个list拼装而成的情况，例打卡记录)
	 public static List<String> getUserIds(HttpServletRequest request) {
		 IDataRuleService dataRuleService = ApplicationContextUtil.getContext().getBean(IDataRuleService.class);
		 ISysDepartService sysDepartService = ApplicationContextUtil.getContext().getBean(ISysDepartService.class);
		 ISysUserRoleService sysUserRoleService = ApplicationContextUtil.getContext().getBean(ISysUserRoleService.class);
		 String requestPath = request.getServletPath();
		 List<DataRule> listUrlConcatStr = dataRuleService.listUrlConcatStr(requestPath);
		 LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
		String queryUserDeparts = sysDepartService.getDepartIdByCode(sysUser.getOrgCode());
		 List<String> result = new ArrayList<String>();
		 for (DataRule dataRule : listUrlConcatStr) {
			if(!result.isEmpty()) {
				return result;
			}
			switch (dataRule.getConditionCategory()) {
			case conditionCategoryCurrentUser:
				switch (dataRule.getConditions()) {
				case conditionsIn:
					if(ArrayUtils.contains(dataRule.getConditionResults().split(","), sysUser.getId())) {
					result =	getResultList(dataRule,sysUser.getId());
					}
					break;
				case conditionsNotIn:
					if(!ArrayUtils.contains(dataRule.getConditionResults().split(","), sysUser.getId())) {
						result =	getResultList(dataRule,sysUser.getId());
						}
					break;

				default:
					 result.add("nopermission");
					break;
				}
				break;
			case conditionCategoryCurrentDepart:

				switch (dataRule.getConditions()) {
				case conditionsIn:
					if(ArrayUtils.contains(dataRule.getConditionResults().split(","), queryUserDeparts)) {
					result =	getResultList(dataRule,sysUser.getId());
					}
					break;
				case conditionsNotIn:
					if(!ArrayUtils.contains(dataRule.getConditionResults().split(","), queryUserDeparts)) {
						result =	getResultList(dataRule,sysUser.getId());
						}
					break;

				default:
					 result.add("nopermission");
					break;
				}
				break;
			case conditionCategoryCurrentRole:
				String roleIdByUserId = sysUserRoleService.getRoleIdByUserId(sysUser.getId());
				switch (dataRule.getConditions()) {
				case conditionsIn:
					if(contain(dataRule.getConditionResults(), roleIdByUserId)) {
					result =	getResultList(dataRule,sysUser.getId());
					}
					break;
				case conditionsNotIn:
					if(!contain(dataRule.getConditionResults(), roleIdByUserId)) {
						result =	getResultList(dataRule,sysUser.getId());
						}
					break;

				default:
					 result.add("nopermission");
					break;
				}
				break;

			default:
				 result.add("nopermission");
				break;
			}
		}
	        return result;
	    }
	 /**
	  * 拼装非获取当前用户数据的list
	  * @param dataRule
	  * @return
	  */
	 private static List<String> assembleList(DataRule dataRule) {
		 if(dataRule.getDataJudgeResults()!=null) {
			 String str[] = dataRule.getDataJudgeResults().split(",");
		     return Arrays.asList(str);
		 }
		 List<String> result = new ArrayList<String>();
		 result.add("nopermission");
		 return result;
	 }

		/**
		 * 处理结果集，方法一样 单独拿出来了
		 * @param dataRule
		 * @param userId
		 * @return
		 */
		 private static List<String> getResultList(DataRule dataRule,String userId) {
			List<String> result = new ArrayList<String>();
			 switch (dataRule.getDataJudgeCategory()) {
			case dataJudgeCategoryUser:
				result = assembleList(dataRule);
				break;
			case dataJudgeCategoryDepart:
				result = assembleList(dataRule);
						break;
			case dataJudgeCategorySql:

				if(dataRule.getDataJudgeResults()!=null&&"and1=1".equals(dataRule.getDataJudgeResults().replaceAll(" ", ""))) {
					//全部权限结果传个空的
				}else {
					//其他情况无法使用，暂时不给看
					result.add("nopermission");
				}
				break;
			case dataJudgeCategoryCurrentUserId:
				//获取当前用户id传过去
				result.add(userId);
				break;
			}
			 return result;
		 }
}
